﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using University;

namespace UniversityTests
{
    [TestClass]
    public class CourseTest
    {
        static Student[] sampleStudents;
        static Course sampleCourse;

        [ClassInitialize]
        public static void Initialize(TestContext context)
        {
            sampleStudents = new Student[31];
            for(int i = 0; i < 31; i++)
            {
                sampleStudents[i] = new Student("Student" + i, 20000 + i);
            }
        }

        [TestInitialize]
        public void InitializeEmptyCourse()
        {
            string courseName = "How to be a ninja";
            sampleCourse = new Course(courseName);
        }

        [TestMethod]
        public void CourseConstructor()
        {
            string name = "SampleCourseName"; // TODO: Initialize to an appropriate value
            Course target = new Course(name);
            Assert.IsNotNull(target);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void CourseConstructorEmptyString()
        {
            string name = "";
            Course target = new Course(name);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CourseConstructorNullString()
        {
            Course target = new Course(null);
        }

        [TestMethod]
        public void AddRegularStudent()
        {
            Student student = sampleStudents[0];
            sampleCourse.AddStudent(student);
            Student expected = sampleCourse.FindStudent(student.FacultyNumber);
            Assert.ReferenceEquals(expected, student);

        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void AddNullStudent()
        {
            sampleCourse.AddStudent(null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void AddDuplicateStudent()
        {
            sampleCourse.AddStudent(sampleStudents[0]);
            sampleCourse.AddStudent(sampleStudents[0]);
        }

        [TestMethod]
        [ExpectedException(typeof(Exception), "Course too big.")]
        public void AddThirtyOneStudents()
        {
            for(int i = 0; i < sampleStudents.Length; i++)
            {
                sampleCourse.AddStudent(sampleStudents[i]);
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void RemoveStudentFromEmptyCourse()
        {
            Student student = sampleStudents[1];
            sampleCourse.RemoveStudent(student);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void RemoveUnexistantStudent()
        {
            sampleCourse.AddStudent(sampleStudents[0]);
            sampleCourse.RemoveStudent(sampleStudents[1]);
        }

        [TestMethod]
        public void RemoveRegularStudent()
        {
            sampleCourse.AddStudent(sampleStudents[0]);
            sampleCourse.RemoveStudent(sampleStudents[0]);
            bool actual = sampleCourse.ContainsStudent(sampleStudents[0]);
            bool expected = false;
            Assert.AreEqual(actual, expected);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ContainsStudentNull()
        {
            sampleCourse.ContainsStudent(null);
        }

        [TestMethod]
        public void EmptyCourseContainsStudent()
        {
            bool actual = sampleCourse.ContainsStudent(sampleStudents[0]);
            bool expected = false;
            Assert.AreEqual(actual, expected);
        }

        [TestMethod]
        public void CourseContainsStudent()
        {
            sampleCourse.AddStudent(sampleStudents[0]);
            bool actual = sampleCourse.ContainsStudent(sampleStudents[0]);
            bool expected = true;
            Assert.AreEqual(actual, expected);
        }

        [TestMethod]
        public void CourseDoesntContainStudent()
        {
            sampleCourse.AddStudent(sampleStudents[0]);
            bool actual = sampleCourse.ContainsStudent(sampleStudents[1]);
            bool expected = false;
            Assert.AreEqual(actual, expected);
        }
    }
}
